<?php
/*
* Kusht Mud.
* ----
* The MIT License
* Copyright (c) 2010 Andrew Tutt
* ----
*/

/* Base Object Class
*
* All Objects in the Game Share these Characteristics by Definition
*/

/*
*	This is, inevitably, an extremely messy class because it's guts have to be general.
*	But its incredible usefulness in encapsulating most of the game's functionality
*	across all it's different types of objects is unrivaled.
*/

class BaseObject {
public $template_id;
public $copy_id;			// This if you have ten copies of an object, this can tell them apart
public $name;
public $short_descr;
public $description;

public $thumb;				// The small image (specific to this server/client setup)
public $image; 				// Potentially it has one (specific to this server/client setup)

/* The Horror, the Horror, nontrivial data types in BaseObject. Ack. But necessary and true. */
public $in_object;			// Where it is (BaseObject)
public $was_in_object;		// Where it was (BaseObject)

public $items;				// For use with containers, and people carrying stuff
public $weight;				// You can't see it or touch it, but everybody has it. (And you can see it when you wear that dress).

public $all_flags; 			// Any boolean value of any kind on the object (all options, settings, affects, etc.)
public $affects;			// Array of affects
public $set_name;			// The name of any categorical set to which this item belongs (For rooms, this is sector, for items it might be an EQ set, etc.)

// Database Variables... have to have them...
public $in_object_id;

function __construct() {
	$this->template_id	= uniqid("",true);
	$this->copy_id 		= uniqid("",true);
	$this->items		= array();
	$this->affects 		= array();
	$this->all_flags 	= array();
	
	$this->thumb 		= "";
	$this->image 		= "";
	
	// Ease up on the database;
	$this->weight 		= DEF_NEG;
}

function __clone() {
	$this->copy_id 		= uniqid("",true);
}

/* These functions are EXTREMELY unfinished: Be warned! */
function add_item($object) {
	if($object->set("in_object",$this)===false) { return false; }
	$this->items += array($object->copy_id=>$object);
}	

function rmv_item($object) {
	if($object->set("was_in_object",$this)===false) { return false; }
	unset($this->items[$object->copy_id]);
}	

function in_room() {
	// If it's not in the room directly, the object above it is...
	if(is_a($this,"Room")) {
		return $this;
	} elseif(is_a($this->in_object,"Room")) {
		return $this->in_object; 
	} else {
		// Recursively search
		return $this->in_object->in_room();
	}
	// Should never throw, but might need a check for isset()
	// if you take things out of rooms and then check this
}

function was_in_room() {
	// If it's not in a room directly, the object above it is...
	if(is_a($this->was_in_object,"Room")) {
		return $this->was_in_object;
	} else {
		// Recursively search
		return $this->was_in_object->was_in_room();
	}	
}

/* -- LOWEST LEVEL FUNCTIONS -- */

// -- Database (Permanent Storage)
function save() {
	dbHandler::save($this);
}

function load() {
	$id = func_num_args() ? func_get_arg(0) : $this->template_id;
	set_fields_equal($this,dbHandler::load($this,$id));
	rmv_slashes_object($this);
}

function delete() {
	dbHandler::delete($this);
}

function perm_set($var) { // Permanent (across all instances)
	SET_BIT($this->all_flags,$var);
}

function perm_rmv($var) { // Permanent (across all instances)
	RMV_BIT($this->all_flags,$var);
}

// These functions allow us to be totally agnostic about object
// flags of any kind whatsoever
// -- Flags
function is($flag) {
	return IS_SET($this->all_flags,$flag);
}

function has($flag) {
	return IS_SET($this->all_flags,$flag);
}

function isnt($flag) {
	return !$this->is($flag);
}

function hasnt($flag) {
	return !$this->has($flag);
}

// Assignment through these functions guarantees that an object 
// update goes directly to the (relevant) client
// -- Triggers for Data to Client
function set_bit($var) {
	StateMngr::handleFlagChange($this,$var,true); // We want the flag on
}

function rmv_bit($var) {
	StateMngr::handleFlagChange($this,$var,false); // We want the flag off
}

function set($fieldName,$value) {
	StateMngr::handleStateChange($this,$fieldName,$value);
}
	
}

?>